package com.order.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.order.util.JwtUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT认证过滤器
 */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                  FilterChain filterChain) throws ServletException, IOException {
        
        // 检查是否是公开接口，如果是则直接放行
        String requestPath = request.getRequestURI();
        if (isPublicPath(requestPath)) {
            filterChain.doFilter(request, response);
            return;
        }
        
        String token = getTokenFromRequest(request);
        
        if (token != null) {
            try {
                // 使用新的验证方法获取验证结果信息
                String username = jwtUtil.getUsernameFromToken(token);
                String validationResult = jwtUtil.validateTokenWithMessage(token, username);
                
                if ("Token验证成功".equals(validationResult)) {
                    if (SecurityContextHolder.getContext().getAuthentication() == null) {
                        // 创建认证对象
                        UsernamePasswordAuthenticationToken authentication = 
                            new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
                        
                        // 设置到安全上下文
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                    }
                } else {
                    // Token验证失败，返回错误信息
                    sendErrorResponse(response, HttpServletResponse.SC_UNAUTHORIZED, validationResult);
                    return;
                }
            } catch (Exception e) {
                // 捕获其他异常，返回错误信息
                sendErrorResponse(response, HttpServletResponse.SC_UNAUTHORIZED, "Token验证失败: " + e.getMessage());
                return;
            }
        } else {
            // 没有token，返回未授权错误
            sendErrorResponse(response, HttpServletResponse.SC_UNAUTHORIZED, "请先登录");
            return;
        }
        
        filterChain.doFilter(request, response);
    }
    
    /**
     * 发送错误响应
     */
    private void sendErrorResponse(HttpServletResponse response, int status, String message) throws IOException {
        response.setStatus(status);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("code", status);
        errorResponse.put("message", message);
        errorResponse.put("timestamp", System.currentTimeMillis());
        
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.writeValue(response.getWriter(), errorResponse);
    }

    /**
     * 检查是否是公开路径
     */
    private boolean isPublicPath(String path) {
        String[] publicPaths = {
            "/api/auth/login",
            "/api/auth/register", 
            "/api/category/list",
            "/api/order/list"
        };
        
        for (String publicPath : publicPaths) {
            if (path.equals(publicPath)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 从请求中获取token
     */
    private String getTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}